"""
医生 CRUD 操作
"""
from typing import Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from  crud.base import CRUDBase
from  models.doctor import Doctor
from  schemas.doctor import DoctorCreate, DoctorUpdate
from  core.security import get_password_hash


class CRUDDoctor(CRUDBase[Doctor, DoctorCreate, DoctorUpdate]):
    """医生CRUD操作"""
    
    async def get_by_phone(self, db: AsyncSession, *, phone: str) -> Optional[Doctor]:
        """
        根据手机号获取医生
        
        Args:
            db: 数据库会话
            phone: 手机号
        
        Returns:
            医生对象或None
        """
        result = await db.execute(
            select(self.model).where(self.model.phone == phone)
        )
        return result.scalar_one_or_none()
    
    async def create(self, db: AsyncSession, *, obj_in: DoctorCreate) -> Doctor:
        """
        创建医生（重写以处理密码哈希）
        
        Args:
            db: 数据库会话
            obj_in: 医生创建模型
        
        Returns:
            创建的医生对象
        """
        db_obj = Doctor(
            name=obj_in.name,
            phone=obj_in.phone,
            gender=obj_in.gender,
            title=obj_in.title,
            password_hash=get_password_hash(obj_in.password),
            status=1
        )
        db.add(db_obj)
        await db.flush()
        await db.refresh(db_obj)
        return db_obj
    
    async def update_password(
        self, 
        db: AsyncSession, 
        *, 
        doctor: Doctor, 
        new_password: str
    ) -> Doctor:
        """
        更新医生密码
        
        Args:
            db: 数据库会话
            doctor: 医生对象
            new_password: 新密码
        
        Returns:
            更新后的医生对象
        """
        doctor.password_hash = get_password_hash(new_password)
        db.add(doctor)
        await db.flush()
        await db.refresh(doctor)
        return doctor
    
    async def authenticate(
        self, 
        db: AsyncSession, 
        *, 
        phone: str, 
        password: str
    ) -> Optional[Doctor]:
        """
        验证医生登录
        
        Args:
            db: 数据库会话
            phone: 手机号
            password: 密码
        
        Returns:
            验证成功返回医生对象，失败返回None
        """
        #导入verify_password函数：用于验证密码是否正确
        from  core.security import verify_password
        
        doctor = await self.get_by_phone(db, phone=phone)
        if not doctor:
            return None
        if not verify_password(password, doctor.password_hash):
            return None
        return doctor
    
    async def get_by_phone_and_name(
        self,
        db: AsyncSession,
        *,
        phone: str,
        name: str
    ) -> Optional[Doctor]:
        """
        根据手机号和姓名获取医生（用于忘记密码）
        
        Args:
            db: 数据库会话
            phone: 手机号
            name: 姓名
        
        Returns:
            医生对象或None
        """
        result = await db.execute(
            select(self.model)
            .where(self.model.phone == phone)
            .where(self.model.name == name)
            .where(self.model.status == 1)
        )
        return result.scalar_one_or_none()
    
    async def reset_password(
        self,
        db: AsyncSession,
        *,
        doctor: Doctor,
        default_password: str = "123456"
    ) -> Doctor:
        """
        重置医生密码为默认密码
        
        Args:
            db: 数据库会话
            doctor: 医生对象
            default_password: 默认密码（默认为123456）
        
        Returns:
            更新后的医生对象
        """
        doctor.password_hash = get_password_hash(default_password)#使用get_password_hash函数生成密码哈希
        from datetime import datetime, timezone
        doctor.updated_at = datetime.now(timezone.utc)
        db.add(doctor)
        await db.flush()
        await db.refresh(doctor)
        return doctor
    
    async def get_all_active(self, db: AsyncSession) -> list[Doctor]:
        """
        获取所有活跃的医生
        
        Args:
            db: 数据库会话
        
        Returns:
            所有活跃医生列表
        """
        result = await db.execute(
            select(self.model).where(self.model.status == 1)
        )
        return list(result.scalars().all())
    
    async def update_doctor_info(
        self,
        db: AsyncSession,
        *,
        doctor: Doctor,
        update_data: dict
    ) -> Doctor:
        """
        更新医生基本信息（不包括密码）
        
        Args:
            db: 数据库会话
            doctor: 医生对象
            update_data: 要更新的数据字典
        
        Returns:
            更新后的医生对象
        """
        from datetime import datetime, timezone
        
        # 添加更新时间
        update_data["updated_at"] = datetime.now(timezone.utc)
        
        # 更新字段
        for key, value in update_data.items():
            setattr(doctor, key, value)
        
        db.add(doctor)
        await db.flush()
        await db.refresh(doctor)
        return doctor
    
    async def soft_delete(
        self,
        db: AsyncSession,
        *,
        doctor: Doctor
    ) -> Doctor:
        """
        软删除医生（将 status 设为 0）
        
        Args:
            db: 数据库会话
            doctor: 医生对象
        
        Returns:
            删除后的医生对象
        """
        from datetime import datetime, timezone
        
        doctor.status = 0
        doctor.updated_at = datetime.now(timezone.utc)
        db.add(doctor)
        await db.flush()
        await db.refresh(doctor)
        return doctor


# 创建全局实例
doctor = CRUDDoctor(Doctor)


